﻿using Engine;
using SAGhoul.ParticleSystem;
using Game;
using GameEntitySystem;
using System.Collections.Generic;
using System.Linq;
using TemplatesDatabase;

namespace SAGhoul
{
    public class SubsystemBizarreBombBlockBehavior : SubsystemBlockBehavior, IUpdateable  //奇异雷万象天引
    {
        // 子系统引用
        public SubsystemGameInfo m_subsystemGameInfo;
        public SubsystemTime m_subsystemTime;
        public SubsystemBlockBehaviors m_subsystemBlockBehaviors;
        public SubsystemExplosions m_subsystemExplosions;
        public SubsystemProjectiles m_subsystemProjectiles;
        public SubsystemBodies m_subsystemBodies;
        public SubsystemCreatureSpawn m_subsystemCreatureSpawn;
        public SubsystemAudio m_subsystemAudio;
        public SubsystemParticles m_subsystemParticles;
        public SubsystemNoise m_subsystemNoise;
        public SubsystemSAGArtifactBlockBehavior m_subsystemSAGArtifactBlockBehavior;

        // 抛射体管理
        public Dictionary<Projectile, bool> m_projectiles = [];
        public Dictionary<Projectile, double> m_attractionTriggerTimes = [];

        public Game.Random m_random = new();

        public override int[] HandledBlocks => new int[0];
        public UpdateOrder UpdateOrder => UpdateOrder.Default;

        public override void Load(ValuesDictionary valuesDictionary)
        {
            base.Load(valuesDictionary);

            // 初始化所有子系统
            m_subsystemGameInfo = Project.FindSubsystem<SubsystemGameInfo>(true);
            m_subsystemTime = Project.FindSubsystem<SubsystemTime>(true);
            m_subsystemExplosions = Project.FindSubsystem<SubsystemExplosions>(true);
            m_subsystemProjectiles = Project.FindSubsystem<SubsystemProjectiles>(true);
            m_subsystemBlockBehaviors = Project.FindSubsystem<SubsystemBlockBehaviors>(true);
            m_subsystemBodies = Project.FindSubsystem<SubsystemBodies>(true);
            m_subsystemCreatureSpawn = Project.FindSubsystem<SubsystemCreatureSpawn>(true);
            m_subsystemAudio = Project.FindSubsystem<SubsystemAudio>(true);
            m_subsystemParticles = Project.FindSubsystem<SubsystemParticles>(true);
            m_subsystemNoise = Project.FindSubsystem<SubsystemNoise>(true);
			m_subsystemSAGArtifactBlockBehavior = Project.FindSubsystem<SubsystemSAGArtifactBlockBehavior>(true);

            // 初始化现有抛射体
            foreach (Projectile projectile in m_subsystemProjectiles.Projectiles)
            {
                ScanProjectile(projectile);
            }

            // 注册事件
            m_subsystemProjectiles.ProjectileAdded += ScanProjectile;
            m_subsystemProjectiles.ProjectileRemoved += RemoveProjectile;
        }

        // 扫描抛射体
        public void ScanProjectile(Projectile projectile)
        {
            if (m_projectiles.ContainsKey(projectile)) return;

            int blockValue = Terrain.ExtractContents(projectile.Value);
            if (!m_subsystemBlockBehaviors.GetBlockBehaviors(blockValue).Contains(this)) return;

            m_projectiles[projectile] = true;
            m_attractionTriggerTimes[projectile] = projectile.CreationTime + 1.0; // 1秒后触发吸引

            projectile.ProjectileStoppedAction = ProjectileStoppedAction.DoNothing;

            // 添加粒子轨迹
            Color trailColor = (blockValue == 228) ? new Color(255, 140, 192) : Color.White;
            m_subsystemProjectiles.AddTrail(projectile, new Vector3(0f, 0.25f, 0.1f),
                new SmokeTrailParticleSystem(20, 0.33f, float.MaxValue, trailColor));
        }

        // 移除抛射体
        public void RemoveProjectile(Projectile projectile)
        {
            m_projectiles.Remove(projectile);
            m_attractionTriggerTimes.Remove(projectile);
        }

        public void Update(float dt)
        {
            if (!m_subsystemTime.PeriodicGameTimeEvent(0.1, 0.0)) return;

            double currentTime = m_subsystemGameInfo.TotalElapsedGameTime;

            foreach (Projectile projectile in m_projectiles.Keys.ToList())
            {
                // 触发吸引效果（创建后1秒）
                if (currentTime >= m_attractionTriggerTimes[projectile] &&
                    currentTime < m_attractionTriggerTimes[projectile] + 0.1)
                {
                    Vector3 position = new(
                        Terrain.ToCell(projectile.Position.X),
                        Terrain.ToCell(projectile.Position.Y),
                        Terrain.ToCell(projectile.Position.Z)
                    );
                    AddAttractionEffect(position, 6f, 15f);
                }

                // 触发爆炸效果
                if (currentTime - projectile.CreationTime > 1.4)
                {
                    m_subsystemSAGArtifactBlockBehavior.AddBizarreExplosion(projectile.Position, 2.5f, 2.3f, projectile.Owner);
					projectile.ToRemove = true;
                }
            }
        }

        // 添加吸引效果
        public void AddAttractionEffect(Vector3 position, float radius, float impulseFactor)
        {
            foreach (var creature in m_subsystemCreatureSpawn.Creatures)
            {
                // 跳过玩家
                if (creature.Entity.FindComponent<ComponentPlayer>() != null) continue;

                ComponentBody body = creature.ComponentBody;
                float distance = Vector3.Distance(body.Position, position);

                if (distance > radius) continue;

                // 计算向心冲量
                Vector3 direction = Vector3.Normalize(position - body.BoundingBox.Center());
                Vector3 impulse = direction * impulseFactor * m_random.Float(0.8f, 1.4f);

                body.ApplyImpulse(impulse);
            }

            // 添加向心收缩的烟花粒子效果
            AddInwardFireworksEffect(position, radius);

            // 添加音效和粒子效果
            m_subsystemAudio.PlayRandomSound("Audio/Artifact/Artifact_Hit", 5f,
                m_random.Float(-0.3f, 0.3f), position, 20f, false);
            m_subsystemNoise.MakeNoise(position, 1f, 20f);
        }

        // 添加向心收缩的烟花粒子效果
        public void AddInwardFireworksEffect(Vector3 center, float radius)
        {
            // 创建一个特殊的烟花粒子系统，粒子从圆周向圆心收缩
            // 缩小初始半径为原来的一半
            var particleSystem = new InwardFireworksParticleSystem(center, radius * 0.5f, 160);
            m_subsystemParticles.AddParticleSystem(particleSystem);
        }
    }

}